Skip to main content

Management API

TideCloak provides a Management API (Keycloak-compatible Admin REST) to manage realms, clients, users, roles, and more. It's ideal for automating provisioning, CI/CD, migrations, and back-office tasks.


1. Prerequisites

  • A running TideCloak server (dev, self-hosted, or managed).
  • An admin user or a confidential client with service account credentials.
  • Network access to the admin endpoints over HTTPS.

Base URLs

  • Modern Keycloak/TideCloak (Quarkus): https://<host>/realms/<realm>/protocol/openid-connect/token Admin REST base: https://<host>/admin/realms/<realm>/...
  • Legacy path (older distros include /auth): https://<host>/auth/realms/<realm>/protocol/openid-connect/token Admin REST base: https://<host>/auth/admin/realms/<realm>/...

Use whichever matches your deployment. Your earlier console URLs should hint which style you're on.


2. Try the API via Swagger

You can experiment with the API using the hosted Swagger UI: https://apidocs.tidecloak.com.

Prereqs

  • A realm (e.g., swagger-realm)
  • A client (e.g., swagger-ui)
  • A user with a linked Tide account

Steps

  1. Set Base URL to your TideCloak host.
  2. Enter the client_id (your client, not admin-cli unless that's what you use).
  3. Click Authorize and sign in with your Tide-linked account, or paste a Bearer token.

Create a confidential client with Service accounts enabled and grant it only the required realm-management roles (least privilege!):

  • Typical roles: view-users, manage-users, view-clients, manage-clients, view-realm, manage-realm (pick only what you need).

Token (Bash)

export HOST="https://<host>"
export REALM="master" # or the admin realm you use for tokens
export CLIENT_ID="admin-bot"
export CLIENT_SECRET="<client-secret>"

curl -sS -X POST "$HOST/realms/$REALM/protocol/openid-connect/token" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=client_credentials" -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET"

4. Common Admin Tasks (cURL)

Replace TOKEN with your access token, and ADMREALM with the realm you are administrating (often a non-master realm).

List users

curl -sS "$HOST/admin/realms/ADMREALM/users?search=bob&first=0&max=20" -H "Authorization: Bearer $TOKEN"

Create a user

curl -sS -X POST "$HOST/admin/realms/ADMREALM/users" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{
"username": "bob",
"email": "bob@example.com",
"enabled": true
}' -i
# On success returns 201 and a Location header with the new user ID.

Assign a realm role to a user

# 1) Get the role representation
ROLE="admin"
ROLE_JSON=$(curl -sS "$HOST/admin/realms/ADMREALM/roles/$ROLE" -H "Authorization: Bearer $TOKEN")

# 2) Map it to the user
curl -sS -X POST "$HOST/admin/realms/ADMREALM/users/$USER_ID/role-mappings/realm" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "[$ROLE_JSON]"

Create a client and fetch its secret

# Create client
curl -sS -X POST "$HOST/admin/realms/ADMREALM/clients" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{
"clientId": "myclient",
"publicClient": false,
"serviceAccountsEnabled": true,
"redirectUris": ["https://app.example.com/*"]
}' -i

# Find client ID by clientId
CID=$(curl -sS "$HOST/admin/realms/ADMREALM/clients?clientId=myclient" -H "Authorization: Bearer $TOKEN" | jq -r '.[0].id')

# Get client secret
curl -sS "$HOST/admin/realms/ADMREALM/clients/$CID/client-secret" -H "Authorization: Bearer $TOKEN"

5. C# HttpClient Examples

Get token (Client Credentials)

using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

var host = "https://<host>";
var realm = "master";
var clientId = "admin-bot";
var clientSecret = "<client-secret>";

using var http = new HttpClient();
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string,string>("grant_type","client_credentials"),
new KeyValuePair<string,string>("client_id",clientId),
new KeyValuePair<string,string>("client_secret",clientSecret),
});
var tokenRes = await http.PostAsync($"{host}/realms/{realm}/protocol/openid-connect/token", content);
var tokenJson = await tokenRes.Content.ReadAsStringAsync();
// parse access_token and use below

List users

http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var res = await http.GetAsync($"{host}/admin/realms/ADMREALM/users?first=0&max=20");
var body = await res.Content.ReadAsStringAsync();


6. Error Handling Cheat-sheet

  • 401 Unauthorized: Missing/expired token.
  • 403 Forbidden: Token lacks required realm-management permissions.
  • 404 Not Found: Wrong ID/realm or insufficient privileges hide resources.
  • 409 Conflict: Duplicate name/constraint violation (e.g., username exists).
  • 400 Bad Request: Invalid payload or parameters.

Log the response body; admin endpoints usually return a useful message.


7. Security & Best Practices

  • Prefer Client Credentials with a minimal-scope service account over password grant.
  • Assign only needed realm-management roles (least privilege).
  • Use HTTPS, rotate secrets, and store them in a secure secret manager.
  • Do not expose admin tokens client-side.
  • For production changes requiring governance, document how they're approved in your process (e.g., IGA/Change Requests).

If your realm uses IGA / Change Requests, add a dedicated section explaining how to create, review, and commit change requests via API (endpoints, required roles, and example payloads).


8. Troubleshooting

  • Token URL mismatch: If you see 404s on /realms/.../protocol/openid-connect/token, try the legacy /auth/realms/... path (and vice-versa).
  • CORS: Admin REST is normally for server-to-server; use it from backend services to avoid CORS.
  • Swagger auth: If "Authorize" fails, verify client type, redirect URIs, and whether the client is public vs confidential.